﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace Frogism.Core {
  public class BudgetItem : IBudgetItem{

      public static BudgetItem CreateWeek(DateTime current, IEnumerable<IAccount> accounts)
      {
      return new BudgetItem("Week", accounts, current.StartOfWeek(), current.EndOfWeek(), current);
    }
      public static BudgetItem CreateWeek(IEnumerable<IAccount> accounts)
      {
      return CreateWeek(DateTime.Now, accounts);
    }
      public static BudgetItem CreateMonth(DateTime current, IEnumerable<IAccount> accounts)
      {

      return new BudgetItem("Month", accounts, current.StartOfMonth(), current.EndOfMonth(), current);
    }
      public static BudgetItem CreateMonth(IEnumerable<IAccount> accounts)
      {
      return CreateMonth(DateTime.Now, accounts);
    }
      public static BudgetItem CreateYear(DateTime current, IEnumerable<IAccount> accounts)
      {
      return new BudgetItem("Year", accounts, current.StartOfYear(), current.EndOfYear(), current);
    }
      public static BudgetItem CreateYear(IEnumerable<IAccount> accounts)
      {
      return CreateYear(DateTime.Now, accounts);
    }
    public static BudgetItem CreateLastWeek(DateTime current, IEnumerable<IAccount> accounts)
    {
      DateTime startDate = current.StartOfWeek().AddDays(-7);
      DateTime endDate = current.EndOfWeek().AddDays(-7);
      return new BudgetItem("Last Week", accounts, startDate, endDate, current);
    }
    public static BudgetItem CreateLastWeek(IEnumerable<IAccount> accounts)
    {
        return CreateLastWeek(DateTime.Now,accounts);
    }

    private IEnumerable<IAccount> Accounts;
    private DateTime _StartDate;
    private DateTime _Now;
    private DateTime _EndDate;
    public DateTime StartDate { get { return _StartDate; } }
    public DateTime Now { get { return _Now; } }
    public DateTime EndDate { get { return _EndDate; } }
    protected BudgetItem(string label, IEnumerable<IAccount> accounts, DateTime startDate, DateTime endDate, DateTime currentDate)
    {
      Accounts = accounts;
      Label = label;
      _StartDate = startDate.CleanDate();
      _EndDate = endDate.CleanDate();
      _Now = currentDate.CleanDate();

    }
    public decimal SpentAverage
    {
        get { return Spent /((TimeSpan)EndDate.Subtract(StartDate)).Days + 1; }
    }
    public string Label {
      get;
      set;
    }

    public decimal Spent {
      get {
        List<ITransaction> expenses = Accounts.SelectMany(a => a.Transactions).ToList();
        return (from e in expenses 
               where e.TransactionType.Value == DBConst.TransactionTypeExpense 
               && e.TransactionDate >= StartDate && e.TransactionDate <= EndDate
                select e.Amount).Sum();
      }
    }
     public static decimal BudgetForDay(DateTime date) {
      string budgetKey;

      if (System.Configuration.ConfigurationSettings.AppSettings["DailyBudget" + date.Year.ToString()] != null) {
        budgetKey = "DailyBudget" + date.Year.ToString();
      } else{
        budgetKey = "DailyBudget";
      }

        return decimal.Parse(System.Configuration.ConfigurationSettings.AppSettings[budgetKey]);


    }
    //public const decimal DailyBudget = 50;
    public decimal Budget {
       get {
         if (EndDate.Year == StartDate.Year) {
           return (((TimeSpan)EndDate.Subtract(StartDate)).Days + 1) * BudgetForDay(EndDate);

         } else {
           decimal tempBudget = 0;
           DateTime tempDate = StartDate;
           while (tempDate <= EndDate) {
             tempBudget += BudgetForDay(tempDate);
             tempDate = tempDate.AddDays(1);
           }
           return tempBudget;
         }
       }
    }

    public decimal Balance {
      get { return Budget - Spent; }
    }

    public decimal BalanceSoFar {
      get {
        return BudgetSoFar - Spent;
      }
    }

    public decimal BudgetSoFar {
      get {
        if(EndDate > Now && StartDate <= Now) {
          decimal budgetSum = 0;
          DateTime i = StartDate;
          while (i <= Now) {
            budgetSum += BudgetForDay(i);
            i = i.AddDays(1);
          }
          return budgetSum;
          
          //return (((TimeSpan)Now.Subtract(StartDate)).Days + 1) * BudgetForDay(StartDate); ;
        } else {
          return Budget;
        }
      }
        
    }
  
  }
}
